Problem description:
Suppose you work at a startup that launched a new credit product a
couple years ago, which consists of a credit card, and such a product
has been growing continuously since its launch. As usual with credit
cards, clients have a monthly payment date. Also, a client is considered
to be on default if he is 30+ days late on a payment.
The data science team has developed a model which estimates the
probability of a client turning delinquent. A high score indicates a low
probability of turning delinquent, and a low score indicates a high
probability of turning delinquent.
You are the analyst advising the company on what policies to adopt
when accepting new applications for a credit card. You are provided with
a csv file with data which might be helpful. What will you recommend to
the business leaders based on this? You can make assumptions and
describe the logic behind them, in case you find some data elements are
missing. Consider general impacts, future analysis, data issues, etc
Solution
Data load & overview
We first load the data and view it:
library(lubridate)
Attaching package: ‘lubridate’
The following objects are masked from ‘package:base’:
date, intersect, setdiff, union
Assumptions about the data
We will assume the columns hold the following data:
origination_month: the year and month
this particular client was originated.
score_band_v2: the score given to this
client by the model the data science team developed.
nb_clients: the ID of the client to
which the score on the score_band_v2 column belongs.
months_since_origination: the number
of months that have passed since origination corresponding for the
number of clients_on_default.
clients_on_default: the number of
clients with delinquent debt that correspond to the number of
months_since_origination
These assumptions imply that we have 2 tables,
describing related phenomena, but at very different aggregation levels,
fused into a single one. We will separate them into:
- client sample data: columns 1, 2 and 3, describing clients, their
date of origination, and the score they originated with.
- clients on default: columns 4 and 5, describing the number of
clients who have defaulted according to the number of months since
origination.
We have deduplicated the client sample data and kept unique
combinations of its 3 columns, since there are no repeating
nb_clients, which we will take to be the ID.
Analysis of clients on default
We have several observations for every number of months from 0 to 15,
the latter of which we will assume is the limit after which the debts
are deemed noncollectable and sold off to a collection company.
We should also assume that the column clients_on_default
is cumulative, so adding up all observations for each
of the number of months since origination will only cause inflated (and
wrong) numbers, as a client who has gone delinquent appearing on month
4, will keep appearing until they settle or restructure. To avoid
inflated numbers, we will use averages, maximum and minimum.
We can see that, on average (as little informative as they usually
are), every additional month since the credit was originated adds around
80 defaulting clients. This is really a low number, but considering the
following:
- that the data across the observations for the same number of months
since origination may be for multiple periods or quarters, and
- that, according to Pareto Principle, 80% of your delinquent debt
could be attributed to 20% of your clients,
Then we must discard this exercise with averages and observe the
maximum across these months, and this maximum reveals more information,
with which we could tell the following story:
- Clients that default on their debt grow at a rate of 400 for each
month added since their origination, for up to 6 months
- After the 6-mo mark, ~500 clients restructure. We have to assume
that these clients are taken off the delinquency status and change
status to “restructuring”.
- At the 9-mo mark, even more clients either settle their outstanding
balance, or restructure, up to the 12-mo mark. This restructuring takes
off delinquency over 1000 clients.
- After the 12-mo mark, less than 500 clients remain delinquent, whose
debt we can assume is deemed noncollectable and sold off to collection
companies.
Let’s see now if these patterns also hold for individual clients on
the clients_sample_data.
Analysis of sample of clients
We have assumed that the first 3 columns of the original data is a
sample of the clients, so we will attempt to create a dataset very
similar to the one in the previous section, with data from this sample,
and considering these 2 critical assumptions
Number of months since origination
We will count the number of months since origination up to present
day, June 10th, 2022
client_sample_orig_dates = client_sample |>
mutate(origination_date = interval(origination_date, now()) %/% months(1))
Error in mutate(client_sample, origination_date = interval(origination_date, :
could not find function "mutate"
Translation of scores to delinquency
We explore the distribution of scores to establish a threshold for
delinquency.
But
LS0tDQp0aXRsZTogIkNoYWxsZW5nZSBmb3IgdGhlIHBvc2l0aW9uIG9mIEJBIERpcmVjdG9yIEAgS3Vlc2tpIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyBQcm9ibGVtIGRlc2NyaXB0aW9uOg0KDQpTdXBwb3NlIHlvdSB3b3JrIGF0IGEgc3RhcnR1cCB0aGF0IGxhdW5jaGVkIGEgbmV3IGNyZWRpdCBwcm9kdWN0IGEgY291cGxlIHllYXJzIGFnbywgd2hpY2ggY29uc2lzdHMgb2YgYSBjcmVkaXQgY2FyZCwgYW5kIHN1Y2ggYSBwcm9kdWN0IGhhcyBiZWVuIGdyb3dpbmcgY29udGludW91c2x5IHNpbmNlIGl0cyBsYXVuY2guIEFzIHVzdWFsIHdpdGggY3JlZGl0IGNhcmRzLCBjbGllbnRzIGhhdmUgYSBtb250aGx5IHBheW1lbnQgZGF0ZS4gQWxzbywgYSBjbGllbnQgaXMgY29uc2lkZXJlZCB0byBiZSBvbiBkZWZhdWx0IGlmIGhlIGlzIDMwKyBkYXlzIGxhdGUgb24gYSBwYXltZW50Lg0KDQpUaGUgZGF0YSBzY2llbmNlIHRlYW0gaGFzIGRldmVsb3BlZCBhIG1vZGVsIHdoaWNoIGVzdGltYXRlcyB0aGUgcHJvYmFiaWxpdHkgb2YgYSBjbGllbnQgdHVybmluZyBkZWxpbnF1ZW50LiBBIGhpZ2ggc2NvcmUgaW5kaWNhdGVzIGEgbG93IHByb2JhYmlsaXR5IG9mIHR1cm5pbmcgZGVsaW5xdWVudCwgYW5kIGEgbG93IHNjb3JlIGluZGljYXRlcyBhIGhpZ2ggcHJvYmFiaWxpdHkgb2YgdHVybmluZyBkZWxpbnF1ZW50Lg0KDQpZb3UgYXJlIHRoZSBhbmFseXN0IGFkdmlzaW5nIHRoZSBjb21wYW55IG9uIHdoYXQgcG9saWNpZXMgdG8gYWRvcHQgd2hlbiBhY2NlcHRpbmcgbmV3IGFwcGxpY2F0aW9ucyBmb3IgYSBjcmVkaXQgY2FyZC4gWW91IGFyZSBwcm92aWRlZCB3aXRoIGEgY3N2IGZpbGUgd2l0aCBkYXRhIHdoaWNoIG1pZ2h0IGJlIGhlbHBmdWwuIFdoYXQgd2lsbCB5b3UgcmVjb21tZW5kIHRvIHRoZSBidXNpbmVzcyBsZWFkZXJzIGJhc2VkIG9uIHRoaXM/IFlvdSBjYW4gbWFrZSBhc3N1bXB0aW9ucyBhbmQgZGVzY3JpYmUgdGhlIGxvZ2ljIGJlaGluZCB0aGVtLCBpbiBjYXNlIHlvdSBmaW5kIHNvbWUgZGF0YSBlbGVtZW50cyBhcmUgbWlzc2luZy4gQ29uc2lkZXIgZ2VuZXJhbCBpbXBhY3RzLCBmdXR1cmUgYW5hbHlzaXMsIGRhdGEgaXNzdWVzLCBldGMNCg0KIyBTb2x1dGlvbg0KDQojIyBEYXRhIGxvYWQgJiBvdmVydmlldw0KDQpXZSBmaXJzdCBsb2FkIHRoZSBkYXRhIGFuZCB2aWV3IGl0Og0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCg0KZGF0YSA9IHJlYWRfY3N2KCcuL2RhdGEvcmF3L2FuYWx5dGljc19jaGFsbGVuZ2UuY3N2JykNCmhlYWQoZGF0YSwgNTApDQpgYGANCg0KIyMgQXNzdW1wdGlvbnMgYWJvdXQgdGhlIGRhdGENCg0KV2Ugd2lsbCBhc3N1bWUgdGhlIGNvbHVtbnMgaG9sZCB0aGUgZm9sbG93aW5nIGRhdGE6DQoNCjEuICoqYG9yaWdpbmF0aW9uX21vbnRoYCoqOiB0aGUgeWVhciBhbmQgbW9udGggdGhpcyBwYXJ0aWN1bGFyIGNsaWVudCB3YXMgb3JpZ2luYXRlZC4NCjIuICoqYHNjb3JlX2JhbmRfdjJgKio6IHRoZSBzY29yZSBnaXZlbiB0byB0aGlzIGNsaWVudCBieSB0aGUgbW9kZWwgdGhlIGRhdGEgc2NpZW5jZSB0ZWFtIGRldmVsb3BlZC4NCjMuICoqYG5iX2NsaWVudHNgKio6IHRoZSBJRCBvZiB0aGUgY2xpZW50IHRvIHdoaWNoIHRoZSBzY29yZSBvbiB0aGUgYHNjb3JlX2JhbmRfdjJgIGNvbHVtbiBiZWxvbmdzLg0KNC4gKipgbW9udGhzX3NpbmNlX29yaWdpbmF0aW9uYCoqOiB0aGUgbnVtYmVyIG9mIG1vbnRocyB0aGF0IGhhdmUgcGFzc2VkIHNpbmNlIG9yaWdpbmF0aW9uIGNvcnJlc3BvbmRpbmcgZm9yIHRoZSBudW1iZXIgb2YgYGNsaWVudHNfb25fZGVmYXVsdGAuDQo1LiAqKmBjbGllbnRzX29uX2RlZmF1bHRgKio6IHRoZSBudW1iZXIgb2YgY2xpZW50cyB3aXRoIGRlbGlucXVlbnQgZGVidCB0aGF0IGNvcnJlc3BvbmQgdG8gdGhlIG51bWJlciBvZiBgbW9udGhzX3NpbmNlX29yaWdpbmF0aW9uYA0KDQoqKlRoZXNlIGFzc3VtcHRpb25zIGltcGx5IHRoYXQgd2UgaGF2ZSAyIHRhYmxlcyoqLCBkZXNjcmliaW5nIHJlbGF0ZWQgcGhlbm9tZW5hLCBidXQgYXQgdmVyeSBkaWZmZXJlbnQgYWdncmVnYXRpb24gbGV2ZWxzLCBmdXNlZCBpbnRvIGEgc2luZ2xlIG9uZS4gV2Ugd2lsbCBzZXBhcmF0ZSB0aGVtIGludG86DQoNCjEuIGNsaWVudCBzYW1wbGUgZGF0YTogY29sdW1ucyAxLCAyIGFuZCAzLCBkZXNjcmliaW5nIGNsaWVudHMsIHRoZWlyIGRhdGUgb2Ygb3JpZ2luYXRpb24sIGFuZCB0aGUgc2NvcmUgdGhleSBvcmlnaW5hdGVkIHdpdGguDQoyLiBjbGllbnRzIG9uIGRlZmF1bHQ6IGNvbHVtbnMgNCBhbmQgNSwgZGVzY3JpYmluZyB0aGUgbnVtYmVyIG9mIGNsaWVudHMgd2hvIGhhdmUgZGVmYXVsdGVkIGFjY29yZGluZyB0byB0aGUgbnVtYmVyIG9mIG1vbnRocyBzaW5jZSBvcmlnaW5hdGlvbi4NCg0KYGBge3J9DQoNCmNsaWVudF9zYW1wbGUgPSBkYXRhIHw+IA0KICBzZWxlY3Qob3JpZ2luYXRpb25fbW9udGgsIHNjb3JlX2JhbmRfdjIsIG5iX2NsaWVudHMpIHw+IA0KICBkaXN0aW5jdCgpIHw+IA0KICBtdXRhdGUob3JpZ2luYXRpb25fZGF0ZSA9IGFzLkRhdGUoc3RyX2Mob3JpZ2luYXRpb25fbW9udGgsICctMDEnKSksDQogICAgICAgICBvcmlnaW5hdGlvbl95ZWFyID0gYXNfZmFjdG9yKHN0cl9zcGxpdChvcmlnaW5hdGlvbl9tb250aCwnLScpW1sxXV1bMV0pLCANCiAgICAgICAgIG9yaWdpbmF0aW9uX21vbnRoID0gYXNfZmFjdG9yKG1vbnRoLm5hbWVbYXMubnVtZXJpYyhzdHJfc3BsaXQob3JpZ2luYXRpb25fbW9udGgsJy0nKVtbMV1dWzJdKV0pLCANCiAgICAgICAgIHNjb3JlX2JhbmRfdjIgPSBhc19mYWN0b3Ioc2NvcmVfYmFuZF92MiksIA0KICAgICAgICAgY2xpZW50X2lkID0gYXNfZmFjdG9yKG5iX2NsaWVudHMpKQ0KDQpjbGllbnRzX29uX2RlZmF1bHQgPSBkYXRhIHw+IA0KICBzZWxlY3QobW9udGhzX3NpbmNlX29yaWdpbmF0aW9uLCBjbGllbnRzX29uX2RlZmF1bHQpIHw+DQogIG11dGF0ZShtb250aHNfc2luY2Vfb3JpZ2luYXRpb24gPSBhc19mYWN0b3IobW9udGhzX3NpbmNlX29yaWdpbmF0aW9uKSkNCg0KaGVhZChjbGllbnRfc2FtcGxlKQ0KaGVhZChjbGllbnRzX29uX2RlZmF1bHQpDQpgYGANCg0KV2UgaGF2ZSBkZWR1cGxpY2F0ZWQgdGhlIGNsaWVudCBzYW1wbGUgZGF0YSBhbmQga2VwdCB1bmlxdWUgY29tYmluYXRpb25zIG9mIGl0cyAzIGNvbHVtbnMsIHNpbmNlIHRoZXJlIGFyZSBubyByZXBlYXRpbmcgYG5iX2NsaWVudHNgLCB3aGljaCB3ZSB3aWxsIHRha2UgdG8gYmUgdGhlIElELg0KDQojIyBBbmFseXNpcyBvZiBjbGllbnRzIG9uIGRlZmF1bHQNCg0KV2UgaGF2ZSBzZXZlcmFsIG9ic2VydmF0aW9ucyBmb3IgZXZlcnkgbnVtYmVyIG9mIG1vbnRocyBmcm9tIDAgdG8gMTUsIHRoZSBsYXR0ZXIgb2Ygd2hpY2ggd2Ugd2lsbCBhc3N1bWUgaXMgdGhlIGxpbWl0IGFmdGVyIHdoaWNoIHRoZSBkZWJ0cyBhcmUgZGVlbWVkIG5vbmNvbGxlY3RhYmxlIGFuZCBzb2xkIG9mZiB0byBhIGNvbGxlY3Rpb24gY29tcGFueS4NCg0KV2Ugc2hvdWxkIGFsc28gYXNzdW1lIHRoYXQgdGhlIGNvbHVtbiBgY2xpZW50c19vbl9kZWZhdWx0YCAqKmlzIGN1bXVsYXRpdmUqKiwgc28gYWRkaW5nIHVwIGFsbCBvYnNlcnZhdGlvbnMgZm9yIGVhY2ggb2YgdGhlIG51bWJlciBvZiBtb250aHMgc2luY2Ugb3JpZ2luYXRpb24gd2lsbCBvbmx5IGNhdXNlIGluZmxhdGVkIChhbmQgd3JvbmcpIG51bWJlcnMsIGFzIGEgY2xpZW50IHdobyBoYXMgZ29uZSBkZWxpbnF1ZW50IGFwcGVhcmluZyBvbiBtb250aCA0LCB3aWxsIGtlZXAgYXBwZWFyaW5nIHVudGlsIHRoZXkgc2V0dGxlIG9yIHJlc3RydWN0dXJlLiBUbyBhdm9pZCBpbmZsYXRlZCBudW1iZXJzLCB3ZSB3aWxsIHVzZSBhdmVyYWdlcywgbWF4aW11bSBhbmQgbWluaW11bS4NCg0KYGBge3IgZmlnLmRpbSA9IGMoNSwgNyl9DQphdmdfY2xpZW50c19vbl9kZWZhdWx0X3Blcl9tb250aHNfc2luY2Vfb3JpZ2luYXRpb24gPSBjbGllbnRzX29uX2RlZmF1bHQgfD4NCiAgZ3JvdXBfYnkobW9udGhzX3NpbmNlX29yaWdpbmF0aW9uKSB8Pg0KICBzdW1tYXJpc2UoYXZnX2NsaWVudHNfb25fZGVmYXVsdCA9IG1lYW4oY2xpZW50c19vbl9kZWZhdWx0KSwNCiAgICAgICAgICAgIG1heF9jbGllbnRzX29uX2RlZmF1bHQgPSBtYXgoY2xpZW50c19vbl9kZWZhdWx0KSwNCiAgICAgICAgICAgIG1pbl9jbGllbnRzX29uX2RlZmF1bHQgPSBtaW4oY2xpZW50c19vbl9kZWZhdWx0KSkNCg0KYXZnX2NsaWVudHNfb25fZGVmYXVsdF9wZXJfbW9udGhzX3NpbmNlX29yaWdpbmF0aW9uDQoNCmZpZyA8LSBjbGllbnRzX29uX2RlZmF1bHQgfD4gDQogIHBsb3RfbHkoeCA9IH5tb250aHNfc2luY2Vfb3JpZ2luYXRpb24sIA0KICAgICAgICAgIHkgPSB+Y2xpZW50c19vbl9kZWZhdWx0LA0KICAgICAgICAgIHNwbGl0ID0gfm1vbnRoc19zaW5jZV9vcmlnaW5hdGlvbiwNCiAgICAgICAgICB0eXBlID0gJ3Zpb2xpbicsDQogICAgICAgICAgYm94ID0gbGlzdCh2aXNpYmxlID0gVCksDQogICAgICAgICAgbWVhbmxpbmUgPSBsaXN0KHZpc2libGUgPSBUKQ0KICAgICAgICAgICkgDQoNCmZpZyA8LSBmaWcgfD4NCiAgbGF5b3V0KA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJNb250aHMgc2luY2Ugb3JpZ2luYXRpb24iKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTnVtYmVyIG9mIGNsaWVudHMgb24gZGVmYXVsdCIsIHplcm9saW5lID0gRikNCiAgICApDQoNCmZpZw0KDQpgYGANCldlIGNhbiBzZWUgdGhhdCwgb24gYXZlcmFnZSAoYXMgbGl0dGxlIGluZm9ybWF0aXZlIGFzIHRoZXkgdXN1YWxseSBhcmUpLCBldmVyeSBhZGRpdGlvbmFsIG1vbnRoIHNpbmNlIHRoZSBjcmVkaXQgd2FzIG9yaWdpbmF0ZWQgYWRkcyBhcm91bmQgODAgZGVmYXVsdGluZyBjbGllbnRzLiBUaGlzIGlzIHJlYWxseSBhIGxvdyBudW1iZXIsIGJ1dCBjb25zaWRlcmluZyB0aGUgZm9sbG93aW5nOg0KDQoxLiB0aGF0IHRoZSBkYXRhIGFjcm9zcyB0aGUgb2JzZXJ2YXRpb25zIGZvciB0aGUgc2FtZSBudW1iZXIgb2YgbW9udGhzIHNpbmNlIG9yaWdpbmF0aW9uIG1heSBiZSBmb3IgbXVsdGlwbGUgcGVyaW9kcyBvciBxdWFydGVycywgYW5kDQoyLiB0aGF0LCBhY2NvcmRpbmcgdG8gUGFyZXRvIFByaW5jaXBsZSwgODAlIG9mIHlvdXIgZGVsaW5xdWVudCBkZWJ0IGNvdWxkIGJlIGF0dHJpYnV0ZWQgdG8gMjAlIG9mIHlvdXIgY2xpZW50cywNCg0KVGhlbiB3ZSBtdXN0IGRpc2NhcmQgdGhpcyBleGVyY2lzZSB3aXRoIGF2ZXJhZ2VzIGFuZCBvYnNlcnZlIHRoZSBtYXhpbXVtIGFjcm9zcyB0aGVzZSBtb250aHMsIGFuZCB0aGlzIG1heGltdW0gcmV2ZWFscyBtb3JlIGluZm9ybWF0aW9uLCB3aXRoIHdoaWNoIHdlIGNvdWxkIHRlbGwgdGhlIGZvbGxvd2luZyBzdG9yeToNCg0KMS4gQ2xpZW50cyB0aGF0IGRlZmF1bHQgb24gdGhlaXIgZGVidCBncm93IGF0IGEgcmF0ZSBvZiA0MDAgZm9yIGVhY2ggbW9udGggYWRkZWQgc2luY2UgdGhlaXIgb3JpZ2luYXRpb24sIGZvciB1cCB0byA2IG1vbnRocw0KMi4gQWZ0ZXIgdGhlIDYtbW8gbWFyaywgfjUwMCBjbGllbnRzIHJlc3RydWN0dXJlLiBXZSBoYXZlIHRvIGFzc3VtZSB0aGF0IHRoZXNlIGNsaWVudHMgYXJlIHRha2VuIG9mZiB0aGUgZGVsaW5xdWVuY3kgc3RhdHVzIGFuZCBjaGFuZ2Ugc3RhdHVzIHRvICJyZXN0cnVjdHVyaW5nIi4NCjMuIEF0IHRoZSA5LW1vIG1hcmssIGV2ZW4gbW9yZSBjbGllbnRzIGVpdGhlciBzZXR0bGUgdGhlaXIgb3V0c3RhbmRpbmcgYmFsYW5jZSwgb3IgcmVzdHJ1Y3R1cmUsIHVwIHRvIHRoZSAxMi1tbyBtYXJrLiBUaGlzIHJlc3RydWN0dXJpbmcgdGFrZXMgb2ZmIGRlbGlucXVlbmN5IG92ZXIgMTAwMCBjbGllbnRzLg0KNC4gQWZ0ZXIgdGhlIDEyLW1vIG1hcmssIGxlc3MgdGhhbiA1MDAgY2xpZW50cyByZW1haW4gZGVsaW5xdWVudCwgd2hvc2UgZGVidCB3ZSBjYW4gYXNzdW1lIGlzIGRlZW1lZCBub25jb2xsZWN0YWJsZSBhbmQgc29sZCBvZmYgdG8gY29sbGVjdGlvbiBjb21wYW5pZXMuDQoNCkxldCdzIHNlZSBub3cgaWYgdGhlc2UgcGF0dGVybnMgYWxzbyBob2xkIGZvciBpbmRpdmlkdWFsIGNsaWVudHMgb24gdGhlIGBjbGllbnRzX3NhbXBsZV9kYXRhYC4NCg0KIyMgQW5hbHlzaXMgb2Ygc2FtcGxlIG9mIGNsaWVudHMNCg0KV2UgaGF2ZSBhc3N1bWVkIHRoYXQgdGhlIGZpcnN0IDMgY29sdW1ucyBvZiB0aGUgb3JpZ2luYWwgZGF0YSBpcyBhIHNhbXBsZSBvZiB0aGUgY2xpZW50cywgc28gd2Ugd2lsbCBhdHRlbXB0IHRvIGNyZWF0ZSBhIGRhdGFzZXQgdmVyeSBzaW1pbGFyIHRvIHRoZSBvbmUgaW4gdGhlIHByZXZpb3VzIHNlY3Rpb24sIHdpdGggZGF0YSBmcm9tIHRoaXMgc2FtcGxlLCBhbmQgY29uc2lkZXJpbmcgdGhlc2UgMiAqKmNyaXRpY2FsIGFzc3VtcHRpb25zKioNCg0KIyMjIE51bWJlciBvZiBtb250aHMgc2luY2Ugb3JpZ2luYXRpb24NCg0KV2Ugd2lsbCBjb3VudCB0aGUgbnVtYmVyIG9mIG1vbnRocyBzaW5jZSBvcmlnaW5hdGlvbiB1cCB0byBwcmVzZW50IGRheSwgKipKdW5lIDEwdGgsIDIwMjIqKg0KDQpgYGB7cn0NCmNsaWVudF9zYW1wbGVfb3JpZ19kYXRlcyA9IGNsaWVudF9zYW1wbGUgfD4NCiAgbXV0YXRlKG9yaWdpbmF0aW9uX2RhdGUgPSBpbnRlcnZhbChvcmlnaW5hdGlvbl9kYXRlLCBub3coKSkgJS8lIG1vbnRocygxKSkNCiAgDQpgYGANCg0KIyMjIFRyYW5zbGF0aW9uIG9mIHNjb3JlcyB0byBkZWxpbnF1ZW5jeQ0KDQpXZSBleHBsb3JlIHRoZSBkaXN0cmlidXRpb24gb2Ygc2NvcmVzIHRvIGVzdGFibGlzaCBhIHRocmVzaG9sZCBmb3IgZGVsaW5xdWVuY3kuDQoNCg0KQnV0IA0KDQo=